package com.atguigu.edu2021.mock.service.impl;

import com.atguigu.edu2021.mock.bean.CourseInfo;
import com.atguigu.edu2021.mock.bean.TestPaper;
import com.atguigu.edu2021.mock.bean.TestPaperQuestion;
import com.atguigu.edu2021.mock.bean.TestQuestionInfo;
import com.atguigu.edu2021.mock.config.AppConfig;
import com.atguigu.edu2021.mock.mapper.TestPaperMapper;
import com.atguigu.edu2021.mock.service.CourseInfoService;
import com.atguigu.edu2021.mock.service.TestPaperQuestionService;
import com.atguigu.edu2021.mock.service.TestPaperService;
import com.atguigu.edu2021.mock.service.TestQuestionInfoService;
import com.atguigu.edu2021.mock.service.adv.impl.AdvServiceImpl;
import com.atguigu.gmall2020.mock.util.RandomCollection;
import com.atguigu.gmall2020.mock.util.RandomNum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>
 * 试卷 试卷 服务实现类
 * </p>
 *
 * @author zhangchen
 * @since 2021-09-05
 */
@Service
public class TestPaperServiceImpl extends AdvServiceImpl<TestPaperMapper, TestPaper> implements TestPaperService {


    Map<Long,List<TestPaper>>  coursePaperCache;


    @Autowired
    CourseInfoService courseInfoService;

    @Autowired
    TestQuestionInfoService testQuestionInfoService;

    @Autowired
    TestPaperQuestionService testPaperQuestionService;

    @Transactional
    public void initPaper(){
        this.removeWithCache();
        testPaperQuestionService.removeWithCache();


        Map<Long, CourseInfo> courseInfoMap = courseInfoService.all(true);

        List<TestPaper>  testPaperList=new ArrayList<>(courseInfoMap.size());
        for (CourseInfo courseInfo : courseInfoMap.values()) {
            TestPaper testPaper = new TestPaper();
            testPaper.setPaperTitle(courseInfo.getCourseName()+"测试");
            testPaper.setCourseId(courseInfo.getId());
            testPaper.setCreateTime(new Date());
            testPaper.setDeleted("0");
            testPaper.setPublisherId(99L);
            testPaperList.add(testPaper);
        }
        saveOrUpdateBatch(testPaperList,1000,true);

         List<TestPaperQuestion> testPaperQuestionALL =new ArrayList<>(courseInfoMap.size()*AppConfig.mock_init_paper_max_q);
        for (TestPaper testPaper : testPaperList) {
            List<TestPaperQuestion> testPaperQuestionList = initTestPaperQuestion(testPaper);
            testPaperQuestionALL.addAll(testPaperQuestionList);
        }
        testPaperQuestionService.saveOrUpdateBatch(testPaperQuestionALL,1000,true);

        loadCache();
    }

    public  List<TestPaperQuestion>  initTestPaperQuestion(TestPaper testPaper ){

            List<TestQuestionInfo> questionInfoList = testQuestionInfoService.list(new QueryWrapper<TestQuestionInfo>().eq("course_id", testPaper.getCourseId()));
            if(questionInfoList.size()> AppConfig.mock_init_paper_max_q){
                List<TestQuestionInfo> testQuestionInfoList = RandomCollection.getSomeFrom(questionInfoList, AppConfig.mock_init_paper_max_q);
                return initQuestInfosToPaperQuestList(testPaper,testQuestionInfoList);
            }else if(questionInfoList.size()%2==0|| questionInfoList.size()==1){
                return initQuestInfosToPaperQuestList(testPaper,questionInfoList);
            }else {
                List<TestQuestionInfo> testQuestionInfoList = RandomCollection.getSomeFrom(questionInfoList, questionInfoList.size()-1);
                return initQuestInfosToPaperQuestList(testPaper,testQuestionInfoList);
            }
    }


    public   List<TestPaperQuestion> initQuestInfosToPaperQuestList(TestPaper testPaper, List<TestQuestionInfo> questionInfoList){
        List<TestPaperQuestion> testPaperQuestionList=new ArrayList<>(questionInfoList.size());
        System.out.println("quest.size:"+questionInfoList.size());
        System.out.println("testPaper:"+testPaper);
        BigDecimal scorePerQ =  new BigDecimal(100 ).divide ( new BigDecimal(questionInfoList.size()) ,1, RoundingMode.HALF_UP);
        for (TestQuestionInfo testQuestionInfo : questionInfoList) {
            TestPaperQuestion testPaperQuestion = new TestPaperQuestion();
            testPaperQuestion.setPaperId(testPaper.getId());
            testPaperQuestion.setScore(scorePerQ);
            testPaperQuestion.setCreateTime(new Date());
            testPaperQuestion.setQuestionId(testQuestionInfo.getId());
            testPaperQuestion.setPublisherId(99L);
            testPaperQuestionList.add(testPaperQuestion);
        }

        return  testPaperQuestionList;
    }


    public TestPaper getRandPaperFromCourse( Long courseId) {

        List<TestPaper> testPaperList = coursePaperCache.get(courseId);
        if(testPaperList!=null){
            TestPaper testPaper = RandomCollection.getOneFrom(testPaperList);
            return testPaper;
        }else{
            return  null;
        }


    }

    @PostConstruct
    protected void loadCache(){
        cache=new ConcurrentHashMap<>();
        coursePaperCache=new ConcurrentHashMap<>();
        List<TestPaper> list = baseMapper.selectPaperWithQuestion();
        loadCache(  list);
        loadCoursePaperMap(  list);

    }

    private void  loadCoursePaperMap(List<TestPaper> list){
        for (TestPaper testPaper : list) {
            List<TestPaper> testPaperList = coursePaperCache.get(testPaper.getCourseId());
            if(testPaperList!=null){
                testPaperList.add(testPaper);
            }else{
                testPaperList = new ArrayList<>();
                testPaperList.add(testPaper);
                coursePaperCache.put(testPaper.getCourseId(),testPaperList);
            }
        }
    }
}
